package edu.spbu.eclipse.xmledit.golubevhritoshin.editors;

import java.io.File;
import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.ParserConfigurationException;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IPathEditorInput;
import org.eclipse.ui.IPropertyListener;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl;

public class SXESyntaxChecker implements IPropertyListener {

	private SXEditor sxEditor;
	private DocumentBuilder docBuilder;
	private SXESyntaxErrors errorHandler;
	private IFile file;
	private String path;
	private boolean syntaxChekingState = true;

	public SXESyntaxChecker(SXEditor sxEditor) {
		this.sxEditor = sxEditor;
		path = ((IPathEditorInput) this.sxEditor.getEditorInput()).getPath()
				.toString();
		file = ((IFileEditorInput) this.sxEditor.getEditorInput()).getFile();
		errorHandler = new SXESyntaxErrors(file);
		try {
			DocumentBuilderFactoryImpl parserFactory = new DocumentBuilderFactoryImpl();
			parserFactory.setNamespaceAware(true);
			docBuilder = parserFactory.newDocumentBuilder();
			docBuilder.setErrorHandler(errorHandler);
		} catch (ParserConfigurationException e) {
		}
	}

	public boolean getSyntaxCheckingState() {
		return syntaxChekingState;
	}

	private Document parse() {
		if (sxEditor.isDirty()) {
			sxEditor.doSave(null);
		}
		try {
			String systemId = new File(path).toURI().toASCIIString();
			errorHandler.removeAllMarkers();
			Document doc = docBuilder.parse(new InputSource(systemId));
			return doc;
		} catch (SAXException e) {
		} catch (IOException ioEx) {
			IMarker errorMarker;
			try {
				errorMarker = file.createMarker(IMarker.PROBLEM);
				errorMarker.setAttribute(IMarker.MESSAGE, ioEx.getMessage());
				errorMarker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
				errorMarker.setAttribute(IMarker.PRIORITY, IMarker.PRIORITY_HIGH);
			} catch (CoreException e) {
			}
		}
		return null;
	}

	public void propertyChanged(Object source, int propId) {
		if (syntaxChekingState && source instanceof SXEditor
				&& IEditorPart.PROP_DIRTY == propId) {
			parse();
		}
	}

	public void setSyntaxCheckingState() {
		syntaxChekingState = !syntaxChekingState;
	}
}
